/*//////////////////////////////////////////////////////////////////////////////
//
//                  INTEL CORPORATION PROPRIETARY INFORMATION
//     This software is supplied under the terms of a license agreement or
//     nondisclosure agreement with Intel Corporation and may not be copied
//     or disclosed except in accordance with the terms of that agreement.
//          Copyright(c) 2003-2008 Intel Corporation. All Rights Reserved.
//
*/

#ifndef __UMC_MP4_PARSER_W_H__
#define __UMC_MP4_PARSER_W_H__

#include "vm_types.h"
#include "ippdefs.h"
#include "umc_data_writer.h"

/*******************DECLARATIONS TYPES********************/

#define MAXTRACKS 1024

typedef struct
{
    Ipp64u    start;      /* byte start in file */
    Ipp64u    end;        /* byte endpoint in file */
    Ipp32u    size;       /* byte size for writing */
    Ipp8s     type[4];
} TM_atom_mp4;

typedef struct
{
    Ipp32f values[9];
} TM_matrix_data;

typedef struct
{
    Ipp32u size_atom;
    Ipp8u version;
    Ipp32s flags;
    Ipp64u creation_time;
    Ipp64u modification_time;
    Ipp32u nTimeScale;
    Ipp64u duration;
    Ipp32f preferred_rate;
    Ipp32f preferred_volume;
    Ipp8s reserved[10];
    TM_matrix_data matrix;
    Ipp32s preview_time;
    Ipp32s preview_duration;
    Ipp32s poster_time;
    Ipp32s selection_time;
    Ipp32s selection_duration;
    Ipp32s current_time;
    Ipp32u next_track_id;
} TM_mvhd_data;

typedef struct
{
    Ipp32u size_atom;
    Ipp8u version;
    Ipp32s flags;
    Ipp16u objectDescriptorID;
    Ipp8u OD_profileAndLevel;
    Ipp8u scene_profileAndLevel;
    Ipp8u audioProfileId;
    Ipp8u videoProfileId;
    Ipp8u graphics_profileAndLevel;
} TM_iods_data;

typedef struct
{
    Ipp32u size_atom;
    Ipp8u version;
    Ipp32s flags;
    Ipp64u creation_time;
    Ipp64u modification_time;
    Ipp32u track_id;
    Ipp32s reserved1;
    Ipp64u duration;
    Ipp8s reserved2[8];
    Ipp32s layer;
    Ipp32s alternate_group;
    Ipp32f volume;
    Ipp32s reserved3;
    TM_matrix_data matrix;
    Ipp32f track_width;
    Ipp32f track_height;
    Ipp32s is_video;
    Ipp32s is_audio;
    Ipp32s is_hint;
} TM_tkhd_data;

typedef struct
{
    Ipp32u size_atom;
    Ipp8u version;
    Ipp32s flags;
    Ipp64u creation_time;
    Ipp64u modification_time;
    Ipp32u nTimeScale;
    Ipp64u duration;
    Ipp16u language;
    Ipp16u pre_defined;
} TM_mdhd_data;

typedef struct
{
    Ipp32u size_atom;
    Ipp64u start;
    Ipp8u version;
    Ipp32s flags;
    Ipp32s decoderConfigLen;
    Ipp8u* decoderConfig;

    Ipp32s objectTypeID;
    Ipp32s streamType;
    Ipp32s bufferSizeDB;
    Ipp32u maxBitrate;
    Ipp32u avgBitrate;

    Ipp16u es_ID;
    Ipp16u ocr_ID;
    Ipp8u  streamDependenceFlag;
    Ipp8u  urlflag;
    Ipp8u  ocrflag;
    Ipp8u  streamPriority;
    Ipp8u* URLString;
} TM_esds_data;

typedef struct
{
    Ipp32u size_atom;
    Ipp8s format[4];
    Ipp8s reserved[6];
    Ipp16u data_reference;

    Ipp32u version;
    Ipp32u revision;
    Ipp8s vendor[4];

    Ipp32s temporal_quality;
    Ipp32s spatial_quality;
    Ipp16u width;
    Ipp16u height;
    Ipp32u dpi_horizontal;
    Ipp32u dpi_vertical;
    Ipp32s data_size;
//    Ipp32s frames_per_sample;
    Ipp8s compressor_name[32];
    Ipp32s depth;
    Ipp32s ctab_id;
    Ipp32f gamma;
    Ipp32s fields;
    Ipp32s field_dominance;

    Ipp16u channels;
    Ipp16u sample_size;
    Ipp32s compression_id;
    Ipp32s packet_size;
    Ipp32u sample_rate;

    Ipp32s maxPktSize;

    TM_esds_data esds;
} TM_stsd_table_data;

typedef struct
{
    Ipp32u size_atom;
    Ipp8u version;
    Ipp32s flags;
    Ipp32u total_entries;
    TM_stsd_table_data *table;
} TM_stsd_data;

typedef struct
{
    Ipp32u sample_count;
    Ipp32u sample_duration;
} TM_stts_table_data;

typedef struct
{
    Ipp32u sample_count;
    Ipp32u sample_duration;
    Ipp32u sample_size;
    Ipp32u sample_flags;
    Ipp32u sample_ct_offset;
} TM_trun_table_data;

typedef struct
{
    Ipp32u size_atom;
    Ipp8u version;
    Ipp32s flags;
    Ipp32u total_entries;
    Ipp32s entries_allocated;
    TM_stts_table_data *table;
} TM_stts_data;

typedef struct
{
    Ipp32s sample;
} TM_stss_table_data;

typedef struct
{
    Ipp32u size_atom;
    Ipp8u version;
    Ipp32u flags;
    Ipp32u total_entries;
    Ipp32u entries_allocated;
    TM_stss_table_data *table;
} TM_stss_data;

typedef struct
{
    Ipp32u chunk;
    Ipp32u samples;
    Ipp32u id;
    Ipp32u first_sample;
} TM_stsc_table_data;

typedef struct
{
    Ipp32u size_atom;
    Ipp8u version;
    Ipp32s flags;
    Ipp32u total_entries;
    Ipp32u entries_allocated;
    TM_stsc_table_data *table;
} TM_stsc_data;

typedef struct
{
    Ipp32u size;
} TM_stsz_table_data;

typedef struct
{
    Ipp32u size_atom;
    Ipp8u version;
    Ipp32s flags;
    Ipp32u sample_size;
    Ipp32u total_entries;
    Ipp32u entries_allocated;
    TM_stsz_table_data *table;
} TM_stsz_data;

typedef struct
{
    Ipp32u offset;
} TM_stco_table_data;

typedef struct
{
    Ipp32u size_atom;
    Ipp8u version;
    Ipp32s flags;
    Ipp32u total_entries;

    TM_stco_table_data *table;
} TM_stco_data;

typedef struct
{
    Ipp64u offset;
} TM_co64_table_data;

typedef struct
{
    Ipp8u version;
    Ipp32s flags;
    Ipp32u total_entries;
    TM_co64_table_data *table;
} TM_co64_data;

typedef struct
{
    Ipp32u sample_count;
    Ipp32u sample_offset;
} TM_ctts_table_data;

typedef struct
{
    Ipp32u size_atom;
    Ipp8u version;
    Ipp32s flags;
    Ipp32u total_entries;
    Ipp32s entries_allocated;
    TM_ctts_table_data *table;
} TM_ctts_data;

typedef struct
{
    Ipp32u size_atom;
    Ipp32s version;
    Ipp32s flags;
    TM_stsd_data stsd;
    TM_stts_data stts;
    TM_stss_data stss;
    TM_stsc_data stsc;
    TM_stsz_data stsz;
    TM_stco_data stco;
    TM_co64_data co64;
    TM_ctts_data ctts;
} TM_stbl_data;

typedef struct
{
    Ipp32u size_atom;
    Ipp8u version;
    Ipp32u flags;
    vm_char component_type[4];
    Ipp8s component_subtype[4];
    Ipp32u component_manufacturer;
    Ipp32u component_flags;
    Ipp32u component_flag_mask;
    vm_char component_name[250];
} TM_hdlr_data;

typedef struct
{
    Ipp32u size;
    Ipp8s type[4];
    Ipp8u version;
    Ipp32s flags;
    vm_char *data_reference;
} TM_dref_table_data;

typedef struct
{
    Ipp32u size_atom;
    Ipp8u version;
    Ipp32s flags;
    Ipp32u total_entries;
    TM_dref_table_data *table;
} TM_dref_data;

typedef struct
{
    Ipp32u size_atom;
    TM_dref_data dref;
} TM_dinf_data;

typedef struct
{
    Ipp32u size_atom;
    Ipp8u version;
    Ipp32s flags;
    Ipp32s graphics_mode;
    Ipp32s opcolor[3];
} TM_vmhd_data;

typedef struct
{
    Ipp32u size_atom;
    Ipp8u version;
    Ipp32s flags;
    Ipp32s balance;
    Ipp32s reserved;
} TM_smhd_data;

typedef struct
{
    Ipp32u size_atom;
    Ipp32s is_video;
    Ipp32s is_audio;
    Ipp32s is_hint;
    TM_vmhd_data vmhd;
    TM_smhd_data smhd;
//    TM_hmhd_data hmhd;
    TM_stbl_data stbl;
    TM_hdlr_data hdlr;
    TM_dinf_data dinf;
} TM_minf_data;

typedef struct
{
    Ipp32u size_atom;
    TM_mdhd_data mdhd;
    TM_minf_data minf;
    TM_hdlr_data hdlr;
} TM_mdia_data;

typedef struct
{
    Ipp32u duration;
    Ipp32u time;
    Ipp32f rate;
} TM_elst_table_data;

typedef struct
{
    Ipp32u size_atom;
    Ipp32u version;
    Ipp32u flags;
    Ipp32u total_entries;
    TM_elst_table_data *table;
} TM_elst_data;

typedef struct
{
    TM_elst_data elst;
} TM_edts_data;

typedef struct
{
    Ipp32s numTracks;
    Ipp32s trackIds[MAXTRACKS];
    void* traks[MAXTRACKS];
} TM_hint_data;

typedef struct
{
    Ipp32u size_atom;
    //TM_dpnd_data    dpnd;
    TM_hint_data hint;
} TM_tref_data;

typedef struct
{
    Ipp32u size_atom;
    TM_tkhd_data tkhd;
    TM_mdia_data mdia;
    TM_edts_data edts;
    TM_tref_data tref;
    TM_hdlr_data hdlr;
} TM_trak_data;

typedef struct
{
    Ipp32u size_atom;
    Ipp8s *copyright;
    Ipp32u copyright_len;
    Ipp8s *name;
    Ipp32u name_len;
    Ipp8s *info;
    Ipp32u info_len;
} TM_udta_data;

typedef struct
{
    Ipp32u size_atom;
    Ipp32u total_tracks;
    TM_mvhd_data mvhd;
    TM_iods_data iods;
    TM_trak_data *trak[MAXTRACKS];
    TM_udta_data udta;
} TM_moov;

struct TM_table_trun{
    Ipp32u        entry_count;
    TM_trun_table_data*  trun;
    Ipp64f       stream_end;
};

typedef struct
{
    Ipp32u size_atom;
    Ipp32u total_tracks;
    TM_table_trun *trun;
    Ipp32u sequence_number;
} TM_moof;

typedef struct
{
    Ipp32u size_atom;
    Ipp32u total_tracks;
} TM_mvex;

/*******************DECLARATIONS FUNCTIONS********************/

Ipp32s Atom_Skip(UMC::DataWriter *dr, TM_atom_mp4 *atom);
Ipp32s Compare_Atom(TM_atom_mp4 *atom, Ipp8s *type);

void Write_head(UMC::DataWriter *dr);
UMC::Status Write_moov(UMC::DataWriter *dr, TM_moov *moov);
UMC::Status Write_moof(UMC::DataWriter *dr, TM_moof *moof);
UMC::Status Write_mvhd(UMC::DataWriter *dr, TM_mvhd_data *mvhd_data);
UMC::Status Write_mdhd(UMC::DataWriter *dr, TM_mdhd_data *mdhd);
UMC::Status Write_hdlr(UMC::DataWriter *dr, TM_mdhd_data *mdhd);
UMC::Status Write_iods(UMC::DataWriter *dr, TM_iods_data *iods);
UMC::Status Write_tkhd(UMC::DataWriter *dr, TM_tkhd_data *tkhd);
UMC::Status Write_mdia(UMC::DataWriter *dr, TM_mdia_data *mdia, TM_atom_mp4 *trak_atom);
UMC::Status Write_minf(UMC::DataWriter *dr, TM_minf_data *minf, TM_atom_mp4 *parent_atom);
UMC::Status Write_tref(UMC::DataWriter *dr, TM_tref_data *tref, TM_atom_mp4 *atom);
//Ipp32s Write_dpnd(UMC::DataWriter *dr, TM_dpnd_data *dpnd);
UMC::Status Write_hdlr(UMC::DataWriter *dr, TM_hdlr_data *hdlr);
//Ipp32s Write_hmhd(UMC::DataWriter *dr, TM_hmhd_data *hmhd);
UMC::Status Write_vmhd(UMC::DataWriter *dw, TM_vmhd_data *vmhd);
UMC::Status Write_smhd(UMC::DataWriter *dw, TM_smhd_data *smhd);
UMC::Status Write_stbl(UMC::DataWriter *dr, TM_minf_data *minf, TM_stbl_data *stbl, TM_atom_mp4 *parent_atom);
UMC::Status Write_stts(UMC::DataWriter *dr, TM_stts_data *stts);
UMC::Status Write_stsd(UMC::DataWriter *dr, TM_minf_data *minf, TM_stsd_data *stsd);
UMC::Status Write_stsc(UMC::DataWriter *dr, TM_stsc_data *stsc);
UMC::Status Write_stss(UMC::DataWriter *dr, TM_stss_data *stss);
UMC::Status Write_stco(UMC::DataWriter *dr, TM_stco_data *stco);
UMC::Status Write_co64(UMC::DataWriter *dr, TM_co64_data *co64);
UMC::Status Write_stsz(UMC::DataWriter *dr, TM_stsz_data *stsz);
UMC::Status Write_ctts(UMC::DataWriter *dr, TM_ctts_data *ctts);
UMC::Status Write_stsd_table(UMC::DataWriter *dr, TM_minf_data *minf, TM_stsd_table_data *table);
UMC::Status Write_trak(UMC::DataWriter *dr, TM_trak_data *trak, TM_atom_mp4 *trak_atom);
UMC::Status Write_stsd_audio(UMC::DataWriter *dr, TM_stsd_table_data *table, TM_atom_mp4 *parent_atom);
UMC::Status Write_stsd_video(UMC::DataWriter *dr, TM_stsd_table_data *table, TM_atom_mp4 *parent_atom);
UMC::Status Write_h264_video(UMC::DataWriter *dr, TM_stsd_table_data *table, TM_atom_mp4 *parent_atom);
UMC::Status Write_stsd_hint(UMC::DataWriter *dr, TM_stsd_table_data *table, TM_atom_mp4 *parent_atom);
UMC::Status Write_esds(UMC::DataWriter *dr, TM_esds_data *esds);
UMC::Status Write_avcC(UMC::DataWriter *dr, TM_esds_data *avcC);
UMC::Status Write_dinf(UMC::DataWriter *dr, TM_dinf_data *dinf, TM_atom_mp4 *dinf_atom);
UMC::Status Write_dref(UMC::DataWriter *dr, TM_dref_data *dref);
UMC::Status Write_dref_table(UMC::DataWriter *dr, TM_dref_table_data *table);
UMC::Status Write_mvex(UMC::DataWriter *dr, TM_mvex *table);

UMC::Status Write_data(UMC::DataWriter *dw, Ipp8s *data, Ipp32s size);

#endif // __UMC_MP4_PARSER_W_H__
